/*
 * @Descripttion: 
 * @version: 
 * @Author: LiuXuFei
 * @Date: 2021-11-24 09:18:39
 * @LastEditors: LiuXuFei
 * @LastEditTime: 2021-11-24 13:29:14
 */
function deepObjectMerge(FirstOBJ, SecondOBJ) { // 深度合并对象
	for (var key in SecondOBJ) {
		FirstOBJ[key] = FirstOBJ[key] && FirstOBJ[key].toString() === "[object Object]" ?
			deepObjectMerge(FirstOBJ[key], SecondOBJ[key]) : FirstOBJ[key] = SecondOBJ[key];
	}
	return FirstOBJ;
}

async function methods(method, obj) {
	obj.method=method
	var options = deepObjectMerge(JSON.parse(JSON.stringify(this.config)), obj)
	options = this.interceptors.request.inuse(options) || options
	options.url = options.baseURL + options.url
	let [err, res] = await uni.request(options)
	
	if (err) {
		return this.interceptors.response.inuse(err) || err
	} else {
		
		return this.interceptors.response.inuse(res) || res
	}
}

class customRequest {
	constructor() {
		this.config = {
			baseURL: '',
			header: {
				'content-type': 'application/json'
			},
			data: null,
			timeout: 10000,
			method: 'GET',
			dataType: 'json',
			responseType: 'text'
		}
		

		this.interceptors = {
			request: {
				use: function(callback) {
					this.inuse = callback
				},
				inuse: () => {}
			},
			response: {
				use: function(callback) {
					this.inuse = callback
				},
				inuse: () => {}
			}
		}
		if (!customRequest.instance) {
			customRequest.instance = this
		}
		return customRequest.instance
	}

	create(obj) {
		deepObjectMerge(this.config, obj)
		return customRequest.getInstance()
	}

	async GET(obj) {
		return await methods.call(this, 'GET', obj)
	}
	async POST(obj) {
		return await methods.call(this, 'POST', obj)
	}
	async PUT(obj) {
		return await methods.call(this, 'PUT', obj)
	}
	async DELETE(obj) {
		return await methods.call(this, 'DELETE', obj)
	}
	static getInstance() {
		if (!this.instance) {
			return this.instance = new customRequest()
		}
		return this.instance
	}
	install(Vue) {
		Vue.prototype.$request = customRequest.getInstance()
	}
}
export default customRequest.getInstance()
